package net.israfil.foundation.collections.nspace;

import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

/**
 * @author cgruber
 *
 * To change this generated comment edit the template variable "typecomment":
 * Window>Preferences>Java>Templates.
 * To enable and disable the creation of type comments go to
 * Window>Preferences>Java>Code Generation.
 */
public class SimpleDimension implements Dimension {

	private final String name;
	private final Set<String> positions = new HashSet<String>();
	private final Set<NSpace> spaces = new HashSet<NSpace>();
	
	public SimpleDimension() {
		name = null;
	}
	
	public SimpleDimension(String name, String ordinal) {
		this.name = name;
		positions.add(ordinal);
	}

	/**
	 * @see org.frugenplat.framework.nspace.Dimension#getName()
	 */
	public String getName() {
		return this.name;
	}

	/**
	 * @see java.util.Collection#size()
	 */
	public int size() {
		return this.positions.size();
	}

	/**
	 * @see java.util.Collection#isEmpty()
	 */
	public boolean isEmpty() {
		throw new UnsupportedOperationException("Dimension cannot have no positions.  Remove the dimension.");
	}

	/**
	 * @see java.util.Collection#contains(java.lang.Object)
	 */
	public boolean contains(Object positions) {
		return this.positions.contains(positions);
	}

	/**
	 * @see java.util.Collection#iterator()
	 */
	public Iterator<String> iterator() {
		return this.positions.iterator();
	}

	/**
	 * @see java.util.Collection#toArray()
	 */
	public String[] toArray() {
		return this.positions.toArray(new String[size()]);
	}

	/**
	 * @see java.util.Collection#toArray(java.lang.Object)
	 */
	public <T> T[] toArray(T[] array) {
		return this.positions.toArray(array);
	}
	
	/**
	 * @see java.util.Collection#add(java.lang.Object)
	 */
	public boolean add(String
			position) {
		boolean result = this.positions.add(position);
		notifyAddPosition((String)position);
		return result;
	}

	/**
	 * @see java.util.Collection#remove(java.lang.Object)
	 */
	public boolean remove(Object position) {
		boolean result = this.positions.remove(position);
		notifyRemovePosition((String)position);
		return result;
	}

	/**
	 * @see java.util.Collection#containsAll(java.util.Collection)
	 */
	public boolean containsAll(Collection<?> positions) {
		return this.positions.containsAll(positions);
	}

	/**
	 * @see java.util.Collection#addAll(java.util.Collection)
	 */
	public boolean addAll(Collection<? extends String> positions) {
		return this.positions.addAll(positions);
	}

	/** 
	 * @see java.util.Collection#retainAll(java.util.Collection)
	 */
	public boolean retainAll(Collection<?> positions) {
		return this.positions.retainAll(positions);
	}

	/**
	 * @see java.util.Collection#removeAll(java.util.Collection)
	 */
	public boolean removeAll(Collection<?> positions) {
		return this.positions.removeAll(positions);
	}

	/**
	 * @see java.util.Collection#clear()
	 */
	public void clear() {
		throw new UnsupportedOperationException("Dimensions must always have one ordinal");
	}



	/**
	 * @see org.frugenplat.framework.nspace.Dimension#abandonNSpace(org.frugenplat.framework.nspace.NSpace)
	 */
	public void abandonNSpace(NSpace n) {
		this.spaces.remove(n);
	}

	/**
	 * @see org.frugenplat.framework.nspace.Dimension#getWithNSpace(org.frugenplat.framework.nspace.NSpace)
	 */
	public void getWithNSpace(NSpace n) {
		this.spaces.add(n);
	}

	/**
	 * @see org.frugenplat.framework.nspace.Dimension#abandonNSpace(org.frugenplat.framework.nspace.NSpace)
	 */
	public void abandonNSpaces(Collection<NSpace> spaces) {
		this.spaces.removeAll(spaces);
	}

	/**
	 * @see org.frugenplat.framework.nspace.Dimension#getWithNSpace(org.frugenplat.framework.nspace.NSpace)
	 */
	public void getWithNSpaces(Collection<NSpace> spaces) {
		this.spaces.addAll(spaces);
	}
	
	private void notifyAddPosition(String position) {
		for (NSpace space : spaces) {
			space.dimensionAddedPosition(this,position);
		}
	}
	
	private void notifyRemovePosition(String position) {
		for (NSpace space : spaces) {
			space.dimensionRemovedPosition(this,position);
		}
	}
	
	@SuppressWarnings("unused")
    private void notifyAddPositions(Collection<String> positions) {
		
	}

	@SuppressWarnings("unused")
    private void notifyRemovePositions(Collection<String> positions) {

	}

	/**
	 * @see java.lang.Object#hashCode()
	 */
	public int hashCode() {
		return name.hashCode();
	}

	/**
	 * @see java.lang.Object#toString()
	 */
	public String toString() {
		StringBuffer sb = new StringBuffer();
		sb.append(super.toString());
		sb.append(" [");
		sb.append(name);
		sb.append("] {");
		for (String s : positions) sb.append(s);
		sb.append("}");
		return sb.toString();
	}

	/**
	 * @see org.frugenplat.framework.nspace.Dimension#addPosition(java.lang.String)
	 */
	public Dimension addPosition(String s) {
		add(s);
		return this;
	}

	/**
	 * @see org.frugenplat.framework.nspace.Dimension#deletePosition(java.lang.String)
	 */
	public Dimension deletePosition(String s) {
		remove(s);
		return this;
	}



}
